socket模拟http请求,socket模拟http文件上传 您所在的位置:网站首页 hutools 上传文件 socket模拟http请求,socket模拟http文件上传

socket模拟http请求,socket模拟http文件上传

2023-03-31 20:19| 来源: 网络整理| 查看: 265

后端接收3个参数: file、remotePath、time

@PostMapping("/upload") public String upload(@RequestParam("file") MultipartFile file, String remotePath, String time) { System.out.println(file); System.out.println(remotePath); System.out.println(time); return "上传成功"; }

前端准备一个form表单

提交

本地新建一个名为:myfile.txt的文本文件,txt文件内容:123456

发送一个form表单请求

请求后抓包如下:

POST http://localhost:8080/upload HTTP/1.1 Host: localhost:8080 Content-Length: 358 Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQSFobk9lz8ATC9Ax ------WebKitFormBoundaryQSFobk9lz8ATC9Ax Content-Disposition: form-data; name="file"; filename="myfile.txt" 123456 ------WebKitFormBoundaryQSFobk9lz8ATC9Ax Content-Disposition: form-data; name="remotePath" 123 ------WebKitFormBoundaryQSFobk9lz8ATC9Ax Content-Disposition: form-data; name="time" 456 ------WebKitFormBoundaryQSFobk9lz8ATC9Ax--

然后 socket 模拟这个报文即可。

----WebKitFormBoundaryQSFobk9lz8ATC9Ax 这个字符串使用uuid模拟即可,保证唯一就行。

封装成http客户端工具

package com.study; import java.io.*; import java.net.Socket; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * Socket模拟Http客户端 * @author * @date 2023/3/31 18:05 */ public class SocketHttpClient { public static void main(String[] args) throws Exception { String url = "http://localhost:8080/upload"; // 要上传的文件 Map files = new HashMap(); // key:文件名 value:文件绝对路径 files.put("myfile.txt", "D:/myfile.txt"); Map params = new HashMap(); // 请求参数:name=vaue params.put("remotePath", "123"); params.put("time", "456"); String sendPost = sendPost(url, null, null); System.out.println(sendPost); } /** * 模拟POST请求 * @param url 请求路径 * @param files 上传的文件 * @param params 请求参数 * @author * @date 2023/3/31 17:42 */ public static String sendPost(String url, Map files, Map params) { Socket socket = null; InputStream inputStream = null; OutputStream outputStream = null; try { URI uri = new URI(url); // 要连接的服务端IP地址和端口 String host = uri.getHost(); int port = uri.getPort(); if (port == -1) { port = 80; } // 与服务端建立连接 socket = new Socket(host, port); socket.setSoTimeout(5000);//读超时 // 建立好连接后,从socket中获取输入流 inputStream = socket.getInputStream(); // 建立好连接后,从socket中获取输出流 outputStream = socket.getOutputStream(); //获取http模拟报文 byte[] httpSocket = getHttpSocket(url, files, params); outputStream.write(httpSocket); outputStream.flush(); //这里需要延时一段时间,等待文件上传完成,再发送终止符 Thread.sleep(1000); socket.shutdownOutput();// 单向关闭输出流,发送流的终止符-1。 byte[] buf = new byte[1024]; int len; StringBuilder sb = new StringBuilder(); //只有当客户端关闭它的输出流的时候,服务端才能取得结尾的-1 while ((len = inputStream.read(buf)) != -1) { // 注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8 sb.append(new String(buf, 0, len, StandardCharsets.UTF_8)); } String result = sb.toString(); if (result != null && result.indexOf("\r\n\r\n") != -1) { return result.substring(result.indexOf("\r\n\r\n") + 4); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (inputStream != null) { inputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (outputStream != null) { outputStream.close(); } } catch (IOException e) { e.printStackTrace(); } try { if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } return null; } /** * 拼接http报文 * @author * @date 2023/3/31 17:47 */ private static byte[] getHttpSocket(String url, Map files, Map params) throws Exception { URI uri = new URI(url); int port = uri.getPort(); if (port == -1) { port = 80; } String boundary = UUID.randomUUID().toString().replace("-", ""); // 请求体 byte[] body = getBody(boundary, files, params); String host = uri.getHost() + ":" + port; ByteArrayOutputStream http = new ByteArrayOutputStream(); http.write(("POST " + url + " HTTP/1.1\r\n").getBytes(StandardCharsets.UTF_8)); http.write(("Content-Type: multipart/form-data; boundary=" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8)); http.write(("Host: " + host + "\r\n").getBytes(StandardCharsets.UTF_8)); http.write(("Content-Length: " + body.length + "\r\n").getBytes(StandardCharsets.UTF_8)); http.write("\r\n".getBytes(StandardCharsets.UTF_8)); http.write(body); return http.toByteArray(); } /** * 拼接http请求体内容 * @author * @date 2023/3/31 17:47 */ private static byte[] getBody(String boundary, Map files, Map params) throws Exception { // 定义存放 body 内容的缓冲区 ByteArrayOutputStream body = new ByteArrayOutputStream(); // 拼接文件部分 if (files != null) { for (Map.Entry entry : files.entrySet()) { body.write(("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8)); // name="file" 是表单name属性,注意要改成跟自己的一致。 body.write(("Content-Disposition: form-data; name=\"file\"; filename=\"" + entry.getKey() + "\"\r\n") .getBytes(StandardCharsets.UTF_8)); body.write("\r\n".getBytes(StandardCharsets.UTF_8)); // 文件绝对路径 String path = entry.getValue(); byte[] buf = new byte[1024]; int len; FileInputStream fis = null; try { // 将文件内容,写入缓冲区 fis = new FileInputStream(path); while ((len = fis.read(buf)) != -1) { body.write(buf, 0, len); } body.write("\r\n".getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { throw e; } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } } // 拼接普通表单参数部分 if (params != null) { for (Map.Entry entry : params.entrySet()) { body.write(("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8)); // 参数名 body.write(("Content-Disposition: form-data; name=\"" + entry.getKey() + "\"\r\n") .getBytes(StandardCharsets.UTF_8)); body.write("\r\n".getBytes(StandardCharsets.UTF_8)); // 参数值 body.write(entry.getValue().getBytes(StandardCharsets.UTF_8)); body.write("\r\n".getBytes(StandardCharsets.UTF_8)); } } if (files != null || params != null) { // 结束标记 body.write(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); body.write("\r\n".getBytes(StandardCharsets.UTF_8)); } return body.toByteArray(); } }



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有